package us.gaaoc.framework.webapp.util;

/**
 * Copyright (c) 2005-2006, www.pdfbox.org
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. Neither the name of pdfbox; nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * http://www.pdfbox.org
 *
 */

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;

import javax.imageio.IIOException;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;

import us.gaaoc.framework.model.Documents;

/**
 * Convert a PDF document to an image.
 *
 * @author <a href="ben@benlitchfield.com">Ben Litchfield</a>
 * @version $Revision: 1.1 $
 */
public class PDFToImage
{


    /**
     * private constructor.
    */
    private PDFToImage()
    {
        //static class
    }

    public static BufferedImage scale(BufferedImage bsrc, double d)
    throws IOException {
    		int width = (int) (bsrc.getWidth() * d);
    		int height = (int) (bsrc.getHeight() * d);
		  BufferedImage bdest =
		     new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		  Graphics2D g = bdest.createGraphics();
		  
		  AffineTransform at =
		     AffineTransform.getScaleInstance((double)width/bsrc.getWidth(),
		         (double)height/bsrc.getHeight());
		  g.drawRenderedImage(bsrc,at);
		  ByteArrayOutputStream boas = new ByteArrayOutputStream();
		  ImageIO.write(bdest,"JPG",boas);
		  return bdest;
 }
    
    public static byte[] toImage(BufferedImageCreator creator, Documents d, int pageNumber)
    {
    	
    	pageNumber = pageNumber - 1;
        String outputPrefix = null;
        String imageType = "jpg";
    
           // PDDocument document = null;
            try
            {
                //document = PDDocument.load( pdfFile );
    
    
                //List pages = document.getDocumentCatalog().getAllPages();
                
                
                    ImageOutputStream output = null; 
                    ImageWriter imageWriter = null;
                    try
                    {
                        //PDPage page = (PDPage)pages.get( pageNumber );
                        
                    	
                        BufferedImage image = creator.createBufferedImage(d.getContent());//scale(creator.createBuffedImage(pdfFile),1.0);

                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        output = ImageIO.createImageOutputStream(baos );
                        boolean foundWriter = false;
                        Iterator writerIter = ImageIO.getImageWritersByFormatName( imageType );
                        while( writerIter.hasNext() && !foundWriter )
                        {
                            try
                            {
                                imageWriter = (ImageWriter)writerIter.next();
                                ImageWriteParam writerParams = imageWriter.getDefaultWriteParam();
                                if(writerParams.canWriteCompressed() )
                                {
                                	
                                    writerParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                                    writerParams.setCompressionQuality(1.0f);
                                }
                                
                                
                                imageWriter.setOutput( output );
                                imageWriter.write( null, new IIOImage( image, null, null), writerParams );
                                foundWriter = true;
                            }
                            catch( IIOException io )
                            {
                                //ignore exception
                            }
                            finally
                            {
                                if( imageWriter != null )
                                {
                                    imageWriter.dispose();
                                }
                            }
                        }
                        if( !foundWriter )
                        {
                            throw new RuntimeException( "Error: no writer found for image type '" + imageType + "'" );
                        }
                        return baos.toByteArray();
                    }
                    finally
                    {
                        if( output != null )
                        {
                            output.flush();
                            output.close();
                        }
                    }
                } catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}            
            finally
            {
            	/*
                if( document != null )
                {
                    try {
						document.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
                }
                */
            }
            return null;
        }
    public static byte[] toImage(BufferedImageCreator creator, String pdfFile, int pageNumber)
    {
    	pageNumber = pageNumber - 1;
        String outputPrefix = null;
        String imageType = "jpg";
     
        if(outputPrefix == null)
        {
            outputPrefix = pdfFile.substring( 0, pdfFile.lastIndexOf( '.' ));
        }
    
           // PDDocument document = null;
            try
            {
                //document = PDDocument.load( pdfFile );
    
    
                //List pages = document.getDocumentCatalog().getAllPages();
                
                
                    ImageOutputStream output = null; 
                    ImageWriter imageWriter = null;
                    try
                    {
                        //PDPage page = (PDPage)pages.get( pageNumber );
                        
                    	
                        BufferedImage image = creator.createBufferedImage(pdfFile);//scale(creator.createBuffedImage(pdfFile),1.0);

                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        output = ImageIO.createImageOutputStream(baos );
                        boolean foundWriter = false;
                        Iterator writerIter = ImageIO.getImageWritersByFormatName( imageType );
                        while( writerIter.hasNext() && !foundWriter )
                        {
                            try
                            {
                                imageWriter = (ImageWriter)writerIter.next();
                                ImageWriteParam writerParams = imageWriter.getDefaultWriteParam();
                                if(writerParams.canWriteCompressed() )
                                {
                                	
                                    writerParams.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                                    writerParams.setCompressionQuality(1.0f);
                                }
                                
                                
                                imageWriter.setOutput( output );
                                imageWriter.write( null, new IIOImage( image, null, null), writerParams );
                                foundWriter = true;
                            }
                            catch( IIOException io )
                            {
                                //ignore exception
                            }
                            finally
                            {
                                if( imageWriter != null )
                                {
                                    imageWriter.dispose();
                                }
                            }
                        }
                        if( !foundWriter )
                        {
                            throw new RuntimeException( "Error: no writer found for image type '" + imageType + "'" );
                        }
                        return baos.toByteArray();
                    }
                    finally
                    {
                        if( output != null )
                        {
                            output.flush();
                            output.close();
                        }
                    }
                } catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}            
            finally
            {
            	/*
                if( document != null )
                {
                    try {
						document.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
                }
                */
            }
            return null;
        }
    

    private static String getImageFormats()
    {
        StringBuffer retval = new StringBuffer();
        String[] formats = ImageIO.getReaderFormatNames();
        for( int i=0; i<formats.length; i++ )
        {
            retval.append( formats[i] );
            if( i+1<formats.length )
            {
                retval.append( "," );
            }
        }
        return retval.toString();
    }
}
